package com.duojuhe.coremodule.chat.im.service.impl;

import com.duojuhe.common.constant.DataScopeConstants;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.coremodule.chat.im.entity.ChatUsersFriends;
import com.duojuhe.coremodule.chat.im.entity.ChatUsersFriendsApply;
import com.duojuhe.coremodule.chat.im.mapper.ChatUsersFriendsApplyMapper;
import com.duojuhe.coremodule.chat.im.mapper.ChatUsersFriendsMapper;
import com.duojuhe.coremodule.chat.im.pojo.dto.friendsapply.*;
import com.duojuhe.coremodule.chat.im.service.ChatUsersFriendsApplyService;
import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.annotation.KeyLock;
import com.duojuhe.common.bean.DataScopeFilterBean;
import com.duojuhe.common.enums.chat.ImChatEnum;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.encryption.md5.MD5Util;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.system.entity.SystemUser;
import com.duojuhe.coremodule.system.mapper.SystemUserMapper;
import com.duojuhe.websocket.EventCodes;
import com.duojuhe.websocket.subscriber.SendChatSubscribeUtil;
import com.duojuhe.websocket.subscriber.SubscribeHandleDto;
import com.duojuhe.websocket.subscriber.message.sendmsg.MessageUntreatedDto;
import com.duojuhe.websocket.subscriber.message.sendmsg.SystemSendMessageDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class ChatUsersFriendsApplyServiceImpl  extends BaseService implements ChatUsersFriendsApplyService {
    @Resource
    private SendChatSubscribeUtil sendChatSubscribeUtil;
    @Resource
    private ChatUsersFriendsApplyMapper chatUsersFriendsApplyMapper;
    @Resource
    private SystemUserMapper systemUserMapper;
    @Resource
    private ChatUsersFriendsMapper chatUsersFriendsMapper;
    /**
     *【好友申请服务接口】分页查询好友申请服务接口
     * @param req
     * @return
     */
    @DataScopeFilter(userId = "t.friend_id",dataScope = DataScopeConstants.SELF_DATA)
    @Override
    public ServiceResult<PageResult<List<QueryMyChatUsersFriendsApplyPageRes>>> queryMyChatUsersFriendsApplyPageResList(QueryMyChatUsersFriendsApplyPageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "createTime desc, applyId desc");
        List<QueryMyChatUsersFriendsApplyPageRes> list = chatUsersFriendsApplyMapper.queryMyChatUsersFriendsApplyPageResList(req);
        return PageHelperUtil.returnServiceResult(req,list);
    }

    /**
     * 好友申请服务接口
     * @param req
     * @return
     */
    @KeyLock(lockKeyParts = "chatUsersFriendsApply",fixedKey = true)
    @Override
    public ServiceResult saveChatUsersFriendsApply(SaveChatUsersFriendsApplyReq req) {
        SystemUser systemUser = systemUserMapper.selectByPrimaryKey(req.getFriendId());
        if (systemUser==null){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //当前登录人
        String userId = getCurrentLoginUserId();
        //申请人和被申请人是同一个人
        if (userId.equals(req.getFriendId())){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //主键ID 当前用户id和好友id的MD5值
        String id = MD5Util.getMD532(userId+req.getFriendId());
        ChatUsersFriends chatUsersFriends = chatUsersFriendsMapper.selectByPrimaryKey(id);
        if (chatUsersFriends!=null&&ImChatEnum.IM_YES_NO.YES.getKey().equals(chatUsersFriends.getIsFriend())){
            return ServiceResult.fail(ErrorCodes.FRIEND_TRUE_ERROR);
        }
        ChatUsersFriendsApply apply = chatUsersFriendsApplyMapper.selectByPrimaryKey(id);
        //构建好友申请对象
        ChatUsersFriendsApply chatUsersFriendsApply = new ChatUsersFriendsApply();
        chatUsersFriendsApply.setApplyId(id);
        chatUsersFriendsApply.setCreateTime(new Date());
        chatUsersFriendsApply.setApplyStatus(ImChatEnum.ApplyStatus.APPLICATION.getKey());
        chatUsersFriendsApply.setApplyDescription(req.getApplyDescription());
        chatUsersFriendsApply.setUserId(userId);
        chatUsersFriendsApply.setFriendId(req.getFriendId());
        chatUsersFriendsApply.setCreateUserId(userId);
        if (apply==null){
            chatUsersFriendsApplyMapper.insertSelective(chatUsersFriendsApply);
        }else {
            chatUsersFriendsApplyMapper.updateByPrimaryKeySelective(chatUsersFriendsApply);
        }
        //发送申请消息
        handleMyFriendApplyUntreatedNum(req.getFriendId());
        return ServiceResult.ok(ErrorCodes.SUCCESS);
    }



    /**
     * 同意 处理好友申请服务接口
     * @param req
     * @return
     */
    @KeyLock(lockKeyParts = "chatUsersFriendsApply",fixedKey = true)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResult acceptChatUsersFriendsApply(AcceptChatUsersFriendsApplyReq req) {
        ChatUsersFriendsApply apply = chatUsersFriendsApplyMapper.selectByPrimaryKey(req.getApplyId());
        if (apply==null || !ImChatEnum.ApplyStatus.APPLICATION.getKey().equals(apply.getApplyStatus())){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //申请人和被申请人是同一个人
        if (apply.getUserId().equals(apply.getFriendId())){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //当前时间
        Date nowDate = new Date();
        //添加主动好友关系
        addToFriends(apply,nowDate);
        //添加被动好友关系
        addFromFriends(apply,nowDate);
        ChatUsersFriendsApply chatUsersFriendsApply = new ChatUsersFriendsApply();
        chatUsersFriendsApply.setApplyId(req.getApplyId());
        chatUsersFriendsApply.setRemark(req.getRemark());
        chatUsersFriendsApply.setHandleTime(nowDate);
        chatUsersFriendsApply.setApplyStatus(ImChatEnum.ApplyStatus.ACCEPT.getKey());
        chatUsersFriendsApplyMapper.updateByPrimaryKeySelective(chatUsersFriendsApply);
        //发送申请消息
        handleMyFriendApplyUntreatedNum(apply.getFriendId());
        return ServiceResult.ok(ErrorCodes.SUCCESS);
    }

    /**
     * 拒绝 处理好友申请服务接口
     * @param req
     * @return
     */
    @KeyLock(lockKeyParts = "chatUsersFriendsApply",fixedKey = true)
    @Override
    public ServiceResult declineChatUsersFriendsApply(DeclineChatUsersFriendsApplyReq req) {
        ChatUsersFriendsApply apply = chatUsersFriendsApplyMapper.selectByPrimaryKey(req.getApplyId());
        if (apply==null || !ImChatEnum.ApplyStatus.APPLICATION.getKey().equals(apply.getApplyStatus())){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //申请人和被申请人是同一个人
        if (apply.getUserId().equals(apply.getFriendId())){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        ChatUsersFriendsApply chatUsersFriendsApply = new ChatUsersFriendsApply();
        chatUsersFriendsApply.setApplyId(req.getApplyId());
        chatUsersFriendsApply.setRemark(req.getRemark());
        chatUsersFriendsApply.setHandleTime(new Date());
        chatUsersFriendsApply.setApplyStatus(ImChatEnum.ApplyStatus.DECLINE.getKey());
        chatUsersFriendsApplyMapper.updateByPrimaryKeySelective(chatUsersFriendsApply);
        //发送申请消息
        handleMyFriendApplyUntreatedNum(apply.getFriendId());
        return ServiceResult.ok(ErrorCodes.SUCCESS);
    }

    /**
     * 查询好友申请未读未处理数量服务接口
     * @param
     * @return
     */
    @KeyLock(lockKeyParts = "chatUsersFriendsApply",fixedKey = true)
    @DataScopeFilter(userId = "t.friend_id",dataScope = DataScopeConstants.SELF_DATA)
    @Override
    public ServiceResult<Integer> queryMyChatUsersFindFriendApplyNum(DataScopeFilterBean dataScope) {
        return ServiceResult.ok(chatUsersFriendsApplyMapper.queryMyChatUsersFindFriendApplyNum(dataScope));
    }




    /**
     * 添加主动好友关系
     * @param apply
     * @param nowDate
     */
    private void addToFriends(ChatUsersFriendsApply apply,Date nowDate){
        SystemUser toSystemUser = systemUserMapper.selectByPrimaryKey(apply.getFriendId());
        if (toSystemUser==null){
            throw new DuoJuHeException(ErrorCodes.PARAM_ERROR);
        }
        //主键ID 当前用户id和好友id的MD5值
        String toId = MD5Util.getMD532(apply.getUserId()+apply.getFriendId());
        ChatUsersFriends toChatUsersFriends = chatUsersFriendsMapper.selectByPrimaryKey(toId);
        //构建主动添加好友信息
        ChatUsersFriends toFriends = new ChatUsersFriends();
        toFriends.setId(toId);
        toFriends.setUserId(apply.getUserId());
        toFriends.setFriendId(apply.getFriendId());
        toFriends.setFriendRemark(toSystemUser.getRealName());
        //toFriends.setUnfriendTime(nowDate);
        toFriends.setCreateUserId(apply.getUserId());
        toFriends.setCreateTime(nowDate);
        toFriends.setIsFriend(ImChatEnum.IM_YES_NO.YES.getKey());
        toFriends.setDirectionCode(ImChatEnum.ApplyDirection.ACTIVE_APPLY.getKey());
        if (toChatUsersFriends==null){
            chatUsersFriendsMapper.insertSelective(toFriends);
        }else{
            chatUsersFriendsMapper.updateByPrimaryKeySelective(toFriends);
        }
    }
    /**
     * 添加被动好友关系
     * @param apply
     * @param nowDate
     */
    private void addFromFriends(ChatUsersFriendsApply apply,Date nowDate){
        SystemUser formSystemUser = systemUserMapper.selectByPrimaryKey(apply.getUserId());
        if (formSystemUser==null){
            throw new DuoJuHeException(ErrorCodes.PARAM_ERROR);
        }
        //主键ID 当前用户id和好友id的MD5值
        String fromId = MD5Util.getMD532(apply.getFriendId()+apply.getUserId());
        ChatUsersFriends fromChatUsersFriends = chatUsersFriendsMapper.selectByPrimaryKey(fromId);
        //构建被动好友关系
        ChatUsersFriends formFriends = new ChatUsersFriends();
        formFriends.setId(fromId);
        formFriends.setUserId(apply.getFriendId());
        formFriends.setFriendId(apply.getUserId());
        formFriends.setFriendRemark(formSystemUser.getRealName());
        formFriends.setCreateTime(nowDate);
        formFriends.setCreateUserId(apply.getFriendId());
        formFriends.setIsFriend(ImChatEnum.IM_YES_NO.YES.getKey());
        formFriends.setDirectionCode(ImChatEnum.ApplyDirection.PASSIVE_APPLY.getKey());
        if (fromChatUsersFriends==null){
            chatUsersFriendsMapper.insertSelective(formFriends);
        }else{
            chatUsersFriendsMapper.updateByPrimaryKeySelective(formFriends);
        }
    }




    /**
     * 处理我的好友申请消息
     * @param userId
     */
    private void handleMyFriendApplyUntreatedNum(String userId){
        try {
            if (StringUtils.isBlank(userId)){
                return;
            }
            //未读数量
            int untreatedNum = chatUsersFriendsApplyMapper.selectCountMyFriendApplyNumByUserId(userId);
            //构建消息对象
            String type = SystemEnum.UNTREATED_TYPE.UNTREATED_FRIEND_APPLY.getKey();
            SystemSendMessageDto sendMessageDto = new SystemSendMessageDto(userId,new MessageUntreatedDto(untreatedNum,type));
            // 异步发送消息
            SubscribeHandleDto<SystemSendMessageDto> subscribeHandleDto = new SubscribeHandleDto<SystemSendMessageDto>();
            subscribeHandleDto.setEventType(EventCodes.EVENT_SYSTEM_MESSAGE.getEvent());
            subscribeHandleDto.setMessageData(sendMessageDto);
            sendChatSubscribeUtil.sendSystemSubscribeMessage(subscribeHandleDto);

        }catch (Exception e){
            log.error("【发送用户好友申请总数出现异常】,用户ID:{}",userId,e);
        }
    }
}
